home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 October / EnigmA AMIGA RUN 22 (1997)(G.R. Edizioni)(IT)[!][issue 1997-10 & 11][EAR-CD VI].iso / recent2 / scaler.lha / scaler.c < prev    next >
C/C++ Source or Header  |  1997-09-08  |  11KB  |  494 lines

  1. /*
  2.     Scaler: A Bars and Pipes tool for scaling control change values.
  3.  
  4.     Copyright (C) 1997 Richard Hagen
  5.         This code is released into the Public Domain, and may be freely
  6.     distributed in its original form.
  7.  
  8.     It is supplied ``as is'', and comes with no warranty.
  9.     This program code was released because it might be useful as a
  10.     starting point for other programmers. However, if any damage arises
  11.     from its use, the original author will not be held liable.
  12.  
  13.     You are free to use and modify this code to your heart's content,
  14.     provided you acknowledge me as the original author in any code
  15.     that you might distribute which is based largely on this code.
  16.  
  17.     I acknowledge that the design of this accessory is influenced
  18.     strongly by the example code supplied with the Rules for Tools
  19.     package. However, I have made substantial contributions of my
  20.     own.
  21.  
  22.     Richard Hagen
  23.     R.Hagen@mailbox.uq.edu.au
  24.     
  25.     History:
  26.         Version 1.0 (8 September 1997)
  27.     Initial release.
  28. */
  29.  
  30. #include "bars.h"
  31. #include <libraries/dos.h>
  32. #include <proto/exec.h>
  33. #include <proto/intuition.h>
  34. #include <proto/graphics.h>
  35. #include <exec/memory.h>
  36. #include <string.h>
  37. #include <intuition/intuition.h>
  38.  
  39. #include "myheader.h"
  40.  
  41. #define SCALER_NAME "Scaler"
  42.  
  43. #define SCALER_ID MAKE_IDS("CCSC")
  44.  
  45. #define SCALER_TYPE    (TOOL_NORMAL)
  46.  
  47. __chip static UWORD scaler[] = { 
  48.   /*------ plane # 0: --------*/
  49.   0x0, 0x0,
  50.   0x0, 0x0,
  51.   0x0, 0x0,
  52.   0x0, 0x0,
  53.   0x0f00, 0x7800,
  54.   0x1000, 0x8000,
  55.   0x1000, 0x8000,
  56.   0x1000, 0x8000,
  57.   0x0f00, 0x7000,
  58.   0x0, 0x0,
  59.   0x0, 0x0,
  60.   0x0, 0x0,
  61.   /*------ plane # 1: --------*/
  62.   0x0, 0x0,
  63.   0x0, 0x0,
  64.   0x0, 0x0,
  65.   0x0, 0x0,
  66.   0x0f00, 0x7800,
  67.   0x1000, 0x8000,
  68.   0x1000, 0x8000,
  69.   0x1000, 0x8000,
  70.   0x0f00, 0x7000,
  71.   0x0, 0x0,
  72.   0x0, 0x0,
  73.   0x0, 0x0,
  74.   /*------ plane # 2: --------*/
  75.   0x0, 0x0,
  76.   0x0018, 0x0,
  77.   0x03ff, 0xc000,
  78.   0x0618, 0x6000,
  79.   0x0f18, 0xf800,
  80.   0x1918, 0x9000,
  81.   0x1099, 0x8800,
  82.   0x305a, 0x8400,
  83.   0x1f99, 0xf800,
  84.   0x003c, 0x0,
  85.   0x0, 0x0,
  86.   0x0, 0x0,
  87. };
  88.  
  89. static struct Image scaler_image = {
  90.   0,0,
  91.   24 , 12 , 3 ,
  92.   &scaler[0],
  93.   0x1f,0x00,
  94.   NULL
  95. };
  96.  
  97. struct ScalerTool {
  98.   struct Tool tool;
  99.   UBYTE controller;    /* The Control Change number that we're scaling. */
  100.   UBYTE min;        /* The minimum value. */
  101.   UBYTE max;        /* The maximum value. */
  102. };
  103.  
  104. static struct ToolMaster master;
  105.  
  106. extern struct Functions *functions;
  107.  
  108. #define INIT_CC        10
  109. #define INIT_MIN    0
  110. #define INIT_MAX    127
  111.  
  112. static void
  113. scaler_init(struct ScalerTool *tool)
  114. {
  115.   tool->tool.touched = TOUCH_INIT;
  116.  
  117.   tool->controller = INIT_CC;
  118.   tool->min = INIT_MIN;
  119.   tool->max = INIT_MAX;
  120. }
  121.  
  122. #define SCALER_CC_GADGET    1
  123. #define SCALER_CCDOWN_GADGET    2
  124. #define SCALER_CCUP_GADGET    3
  125.  
  126. #define SCALER_MIN_GADGET    4
  127. #define SCALER_MINDOWN_GADGET    5
  128. #define SCALER_MINUP_GADGET    6
  129.  
  130. #define SCALER_MAX_GADGET    7
  131. #define SCALER_MAXDOWN_GADGET    8
  132. #define SCALER_MAXUP_GADGET    9
  133.  
  134. /* CC# gadget. */
  135. struct PropInfo ScalerScalerGadget1SInfo = {
  136.   AUTOKNOB+FREEHORIZ,
  137.   -16384, -1,
  138.   16384, -1,
  139. };
  140.  
  141. struct Image ScalerImage1 = {
  142.   0,0,
  143.   102,6,
  144.   0,
  145.   NULL,
  146.   0x0000,0x0000,
  147.   NULL
  148. };
  149.  
  150. struct IntuiText ScalerIText1 = {
  151.   2,0,JAM1,
  152.   -55,1,
  153.   NULL,
  154.   "CC #:",
  155.   NULL
  156. };
  157.  
  158. struct Gadget ScalerGadget1 = {
  159.   NULL,
  160.   65,14,
  161.   100,10,
  162.   GFLG_GADGHBOX|GFLG_GADGHIMAGE,
  163.   RELVERIFY|GADGIMMEDIATE,
  164.   PROPGADGET,
  165.   (APTR)&ScalerImage1,
  166.   NULL,
  167.   &ScalerIText1,
  168.   NULL,
  169.   (APTR)&ScalerScalerGadget1SInfo,
  170.   SCALER_CC_GADGET,
  171.   NULL
  172. };
  173.  
  174. /* Min gadget. */
  175. struct PropInfo ScalerScalerGadget2SInfo = {
  176.   AUTOKNOB+FREEHORIZ,
  177.   -16384, -1,
  178.   16384, -1,
  179. };
  180.  
  181. struct Image ScalerImage2 = {
  182.   0,0,
  183.   102,6,
  184.   0,
  185.   NULL,
  186.   0x0000,0x0000,
  187.   NULL
  188. };
  189.  
  190. struct IntuiText ScalerIText2 = {
  191.   2,0,JAM1,
  192.   -54,1,
  193.   NULL,
  194.   "Min: ",
  195.   NULL
  196. };
  197.  
  198. struct Gadget ScalerGadget2 = {
  199.   &ScalerGadget1,
  200.   65,26,
  201.   100,10,
  202.   GFLG_GADGHBOX|GFLG_GADGHIMAGE,
  203.   RELVERIFY|GADGIMMEDIATE,
  204.   PROPGADGET,
  205.   (APTR)&ScalerImage2,
  206.   NULL,
  207.   &ScalerIText2,
  208.   NULL,
  209.   (APTR)&ScalerScalerGadget2SInfo,
  210.   SCALER_MIN_GADGET,
  211.   NULL
  212. };
  213.  
  214. /* Max gadget. */
  215. struct PropInfo ScalerScalerGadget3SInfo = {
  216.   AUTOKNOB+FREEHORIZ,
  217.   -16384, -1,
  218.   16384, -1,
  219. };
  220.  
  221. struct Image ScalerImage3 = {
  222.   0,0,
  223.   102,6,
  224.   0,
  225.   NULL,
  226.   0x0000,0x0000,
  227.   NULL
  228. };
  229.  
  230. struct IntuiText ScalerIText3 = {
  231.   2,0,JAM1,
  232.   -54,1,
  233.   NULL,
  234.   "Max: ",
  235.   NULL
  236. };
  237.  
  238. struct Gadget ScalerGadget3 = {
  239.   &ScalerGadget2,
  240.   65,38,
  241.   100,10,
  242.   GFLG_GADGHBOX|GFLG_GADGHIMAGE,
  243.   RELVERIFY|GADGIMMEDIATE,
  244.   PROPGADGET,
  245.   (APTR)&ScalerImage3,
  246.   NULL,
  247.   &ScalerIText3,
  248.   NULL,
  249.   (APTR)&ScalerScalerGadget3SInfo,
  250.   SCALER_MAX_GADGET,
  251.   NULL
  252. };
  253.  
  254. #define ScalerGadgetList1 ScalerGadget3
  255.  
  256. struct NewWindow ScalerNewWindowStructure1 = {
  257.   75,85,
  258.   203, 52,
  259.   0,6,
  260.   GADGETDOWN+GADGETUP+CLOSEWINDOW,
  261.   WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH,
  262.   &ScalerGadget3,
  263.   NULL,
  264.   "Scaler",
  265.   NULL,
  266.   NULL,
  267.   5,5,
  268.   -1,-1,
  269.   CUSTOMSCREEN
  270. };
  271.  
  272. /* Writes the value of a proportional slider. Thank goodness
  273.    all the Scaler sliders are identical in range and behaviour! */
  274. __geta4        /* Callback. */
  275. long display_routine(struct Window *window,    /* Window where the gadget lives. */
  276.              struct Gadget *gadget,    /* The gadget itself. */
  277.              unsigned long value)    /* The value to display. */
  278. {
  279.   char text[10];
  280.   struct RastPort *rp = window->RPort;
  281.   Move(rp, 170, 21 + ((gadget->GadgetID - 1) / 3) * 12);
  282.   SetAPen(rp, 1);
  283.   SetBPen(rp, 0);
  284.   SetDrMd(rp, JAM2);
  285.   sprintf(text, "%3ld", value);
  286.   Text(rp, text, 3);
  287.   return value;
  288. }
  289.  
  290. __geta4        /* Callback. */
  291. static struct Event *
  292. processeventcode(struct Event *event)
  293. {
  294.   if (event->type == EVENT_VOICE &&
  295.       event->status == MIDI_CCHANGE)
  296.     {
  297.       struct ScalerTool *tool = (struct ScalerTool *) event->tool;
  298.       if (event->byte1 == tool->controller)
  299.     {
  300.       const short diff = tool->max - tool->min;
  301.       if (diff > 0)
  302.         {
  303.           event->byte2 = ((event->byte2 * (diff + 1)) >> 7) + tool->min;
  304.         }
  305.       else if (diff < 0)
  306.         {
  307.           event->byte2 = tool->min - ((event->byte2 * (1 - diff)) >> 7);
  308.         }
  309.       else if (diff == 0)
  310.         {
  311.           event->byte2 = tool->min;
  312.         }
  313.     }
  314.     }
  315.   
  316.   event->tool = event->tool->next;
  317.   return(event);
  318. }
  319.  
  320. static long
  321. drag_embossed_prop(struct Window *window,
  322.            short id)
  323. {
  324.   const long value = (*functions->DragEmbossedProp)(window, id);
  325.   (*functions->DrawEmbossedProp)(window, id);
  326.  
  327.   return value;
  328. }
  329.  
  330. static long
  331. shift_embossed_prop(struct Window *window,
  332.             short id,
  333.             short shift)
  334. {
  335.   const long value = (*functions->ShiftEmbossedProp)(window, id, shift, 0);
  336.   (*functions->DrawEmbossedProp)(window, id);
  337.  
  338.   return value;
  339. }
  340.  
  341. __geta4        /* Callback. */
  342. void
  343. edittoolcode(struct ScalerTool *tool)
  344. {
  345.   struct IntuiMessage *message;
  346.   struct Window *window;
  347.   long class, code;
  348.   struct Gadget *gadget;
  349.   struct NewWindow *newwindow;
  350.   ScalerNewWindowStructure1.Screen = functions->screen;
  351.  
  352.   if (tool->tool.touched & TOUCH_EDIT)
  353.     {
  354.       ScalerNewWindowStructure1.LeftEdge = tool->tool.left;
  355.       ScalerNewWindowStructure1.TopEdge = tool->tool.top;
  356.       ScalerNewWindowStructure1.Width = tool->tool.width;
  357.       ScalerNewWindowStructure1.Height = tool->tool.height;
  358.     }
  359.   
  360.   if (!tool->tool.touched)
  361.     {
  362.       scaler_init(tool);
  363.     }
  364.  
  365.   newwindow = (struct NewWindow *)
  366.     (*functions->DupeNewWindow)(&ScalerNewWindowStructure1);
  367.   if (!newwindow)
  368.     {
  369.       return;
  370.     }
  371.   newwindow->Title = 0;
  372.   newwindow->Flags |= BORDERLESS;
  373.   newwindow->Flags &= ~0xF;
  374.   newwindow->BlockPen = 0;
  375.   newwindow->DetailPen = 0;
  376.  
  377.   window = (struct Window *) (*functions->FlashyOpenWindow)(newwindow);
  378.   if (!window)
  379.     {
  380.       return;
  381.     }
  382.  
  383.   tool->tool.window = window;
  384.   (*functions->EmbossWindowOn)(window,WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG,
  385.                    SCALER_NAME,(short)-1,(short)-1,0,0);
  386.   for (short i = SCALER_CC_GADGET;
  387.        i <= SCALER_MAX_GADGET;
  388.        i += 3)
  389.     {
  390.       (*functions->FatEmbossedPropOn)(window,i, i + 1, i + 2,
  391.                       (no_prototype) display_routine,
  392.                       128, 1);
  393.     }
  394.   
  395.   (*functions->ModifyEmbossedProp)(window, SCALER_CC_GADGET,
  396.                    tool->controller, 0, 0, 0, 0, 0);
  397.   (*functions->ModifyEmbossedProp)(window, SCALER_MIN_GADGET,
  398.                    tool->min, 0, 0, 0, 0, 0);
  399.   (*functions->ModifyEmbossedProp)(window, SCALER_MAX_GADGET,
  400.                    tool->max, 0, 0, 0, 0, 0);
  401.  
  402.   for (short i = SCALER_CC_GADGET;
  403.        i <= SCALER_MAX_GADGET;
  404.        i += 3)
  405.     {
  406.       (*functions->DrawEmbossedProp)(window, i);
  407.     }
  408.  
  409.   for (;;)
  410.     {
  411.       message = (struct IntuiMessage *) (*functions->GetIntuiMessage)(window);
  412.       class = message->Class;
  413.       code = message->Code;
  414.       gadget = (struct Gadget *) message->IAddress;
  415.       class = (*functions->SystemGadgets)(window,class,gadget,code);
  416.  
  417.       ReplyMsg((struct Message *)message);
  418.       if (class == CLOSEWINDOW)
  419.     {
  420.       break;
  421.     }
  422.       else if (class == GADGETDOWN)
  423.     {
  424.       const short id = gadget->GadgetID;
  425.  
  426.       switch (id)
  427.         {
  428.         case SCALER_CC_GADGET:
  429.           tool->controller = (UBYTE) drag_embossed_prop(window, SCALER_CC_GADGET);
  430.           break;
  431.         case SCALER_CCDOWN_GADGET:
  432.           tool->controller = (UBYTE) shift_embossed_prop(window, SCALER_CC_GADGET, -1);
  433.           break;
  434.         case SCALER_CCUP_GADGET:
  435.           tool->controller = (UBYTE) shift_embossed_prop(window, SCALER_CC_GADGET, 1);
  436.           break;
  437.         case SCALER_MIN_GADGET:
  438.           tool->min = (UBYTE) drag_embossed_prop(window, SCALER_MIN_GADGET);
  439.           break;
  440.         case SCALER_MINDOWN_GADGET:
  441.           tool->min = (UBYTE) shift_embossed_prop(window, SCALER_MIN_GADGET, -1);
  442.           break;
  443.         case SCALER_MINUP_GADGET:
  444.           tool->min = (UBYTE) shift_embossed_prop(window, SCALER_MIN_GADGET, 1);
  445.           break;
  446.         case SCALER_MAX_GADGET:
  447.           tool->max = (UBYTE) drag_embossed_prop(window, SCALER_MAX_GADGET);
  448.           break;
  449.         case SCALER_MAXDOWN_GADGET:
  450.           tool->max = (UBYTE) shift_embossed_prop(window, SCALER_MAX_GADGET, -1);
  451.           break;
  452.         case SCALER_MAXUP_GADGET:
  453.           tool->max = (UBYTE) shift_embossed_prop(window, SCALER_MAX_GADGET, 1);
  454.           break;
  455.         }
  456.     }
  457.       else if (class == GADGETDOWN)
  458.     {
  459.       /* Nothing. */
  460.     }
  461.     }
  462.   tool->tool.window = 0;
  463.   tool->tool.left = window->LeftEdge;
  464.   tool->tool.top = window->TopEdge;
  465.   tool->tool.width = window->Width;
  466.   tool->tool.height = window->Height;
  467.   tool->tool.touched = TOUCH_INIT | TOUCH_EDIT;
  468.   
  469.   for (short i = SCALER_CC_GADGET;
  470.        i <= SCALER_MAX_GADGET;
  471.        i += 3)
  472.     {
  473.       (*functions->FatEmbossedPropOff)(window, i, i + 1, i + 2);
  474.     }
  475.  
  476.   (*functions->EmbossWindowOff)(window);
  477.   (*functions->FlashyCloseWindow)(window);
  478.   (*functions->DeleteNewWindow)(newwindow);
  479. }
  480.  
  481. struct ToolMaster *
  482. inittoolmaster()
  483. {
  484.   memset((char *)&master,0,sizeof(struct ToolMaster));
  485.   master.toolid = SCALER_ID;
  486.   master.image = &scaler_image;
  487.   strcpy(master.name, SCALER_NAME);
  488.   master.edittool = (void_prototype) edittoolcode;
  489.   master.processevent = (event_prototype) processeventcode;
  490.   master.tooltype = SCALER_TYPE;
  491.   master.toolsize = sizeof(struct ScalerTool);
  492.   return(&master);
  493. }
  494.